package com.pokermind.dse.tcp.client.preset;

import java.util.*;

/**
 * 游戏状态追踪器
 * 
 * 追踪玩家筹码、投入、底池等实时状态
 * 
 * @author PokerMind Team
 */
public class GameStateTracker {
    
    private final Map<String, Integer> initialStacks;      // 初始筹码
    private final Map<String, Integer> currentStacks;      // 当前筹码
    private final Map<String, Integer> currentStreetBets;  // 当前街道投入
    private final Map<String, Integer> totalInvested;      // 本手牌总投入
    private int pot;                                       // 底池
    private String currentStreet;                          // 当前街道
    private List<String> boardCards;                       // 公共牌
    
    public GameStateTracker() {
        this.initialStacks = new HashMap<>();
        this.currentStacks = new HashMap<>();
        this.currentStreetBets = new HashMap<>();
        this.totalInvested = new HashMap<>();
        this.pot = 0;
        this.currentStreet = "preflop";
        this.boardCards = new ArrayList<>();
    }
    
    /**
     * 初始化玩家
     */
    public void initPlayer(String playerId, int stack) {
        initialStacks.put(playerId, stack);
        currentStacks.put(playerId, stack);
        currentStreetBets.put(playerId, 0);
        totalInvested.put(playerId, 0);
    }
    
    /**
     * 记录行动
     */
    public void recordAction(String playerId, String action, int amount) {
        // check 和 fold 不影响筹码和底池
        if ("check".equalsIgnoreCase(action) || "fold".equalsIgnoreCase(action)) {
            // check 和 fold 不消耗筹码，不进入底池
            return;
        }
        
        // 更新筹码
        int currentStack = currentStacks.get(playerId);
        currentStacks.put(playerId, currentStack - amount);
        
        // 更新当前街道投入
        int streetBet = currentStreetBets.getOrDefault(playerId, 0);
        currentStreetBets.put(playerId, streetBet + amount);
        
        // 更新总投入
        int invested = totalInvested.getOrDefault(playerId, 0);
        totalInvested.put(playerId, invested + amount);
        
        // 更新底池
        pot += amount;
    }
    
    /**
     * 切换街道
     */
    public void transitionStreet(String newStreet, List<String> newBoardCards) {
        this.currentStreet = newStreet;
        this.boardCards = new ArrayList<>(newBoardCards);
        
        // 清空当前街道投入
        currentStreetBets.clear();
        for (String playerId : currentStacks.keySet()) {
            currentStreetBets.put(playerId, 0);
        }
    }
    
    /**
     * 获取玩家当前筹码
     */
    public int getCurrentStack(String playerId) {
        return currentStacks.getOrDefault(playerId, 0);
    }
    
    /**
     * 计算玩家需要跟注的金额
     */
    public int calculateToCall(String playerId) {
        int maxBet = currentStreetBets.values().stream()
            .max(Integer::compareTo)
            .orElse(0);
        int playerBet = currentStreetBets.getOrDefault(playerId, 0);
        return Math.max(0, maxBet - playerBet);
    }
    
    /**
     * 获取底池
     */
    public int getPot() {
        return pot;
    }
    
    /**
     * 获取当前街道
     */
    public String getCurrentStreet() {
        return currentStreet;
    }
    
    /**
     * 获取公共牌
     */
    public List<String> getBoardCards() {
        return new ArrayList<>(boardCards);
    }
    
    /**
     * 获取玩家本手牌总投入
     */
    public int getTotalInvested(String playerId) {
        return totalInvested.getOrDefault(playerId, 0);
    }
    
    /**
     * 打印状态（调试用）
     */
    public void printState() {
        System.out.println("━━━ 游戏状态 ━━━");
        System.out.println("  街道: " + currentStreet);
        System.out.println("  底池: " + pot);
        System.out.println("  公共牌: " + boardCards);
        System.out.println("  玩家状态:");
        for (String playerId : currentStacks.keySet()) {
            System.out.printf("    %s: 筹码=%d, 本街道投入=%d, 总投入=%d, 需跟注=%d%n",
                playerId,
                currentStacks.get(playerId),
                currentStreetBets.get(playerId),
                totalInvested.get(playerId),
                calculateToCall(playerId)
            );
        }
    }
}

